package rs.udd.web.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import rs.udd.service.UserService;

@Configuration
@EnableWebSecurity
public class UddSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private UserService userService;

	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
		auth
				.userDetailsService(userService)
				.passwordEncoder(passwordEncoder());
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {

		http

				// disable possibility for cross site request forgery
				.csrf()
				.disable()

				.exceptionHandling()
				.accessDeniedPage("/403")
				// URL to which user will be redirected
				.and()

				// all request must be authorized. some of them are anonymous, some of the require certaing role
				.authorizeRequests()
				// lines commented bellow are permitted for anonymous users with permitAll() after each URL in login page configuration
				.antMatchers("/", "/home", "/home/").permitAll()
				.antMatchers("/search", "/search/", "/search/**").permitAll()
				.antMatchers("/browse", "/browse/", "/browse/**").permitAll()
				.antMatchers("/agents/register", "/agents/register/").permitAll()
				.antMatchers("/advertisers/register", "/advertisers/register/").permitAll()
				.antMatchers("/link/confirmation").permitAll()
				.antMatchers("/link/advertiserRegistration").permitAll()

				.anyRequest()
				.authenticated()
				.and()

				// https is commented because it doesn't work. Probably requires additional configuration
				// .requiresChannel()
				// .anyRequest().requiresSecure() // https
				// .and()

				// custom login page
				.formLogin()
				.loginPage("/login").permitAll()
				.loginProcessingUrl("/login").permitAll()
				.failureUrl("/login/failed").permitAll()
				.usernameParameter("username")
				.passwordParameter("password")
				.and()

				// logout
				.logout()
				.invalidateHttpSession(true)
				.logoutUrl("/login/logout").permitAll()
				.logoutSuccessUrl("/logout").permitAll();
	}

	@Override
	public void configure(WebSecurity web) throws Exception {

		web.ignoring().antMatchers("/static/**"); // for static resources
	}

	@Bean
	@Override
	public AuthenticationManager authenticationManagerBean() throws Exception {
		return super.authenticationManagerBean();
	}
	
	@Bean
	public PasswordEncoder passwordEncoder() {
		PasswordEncoder encoder = new BCryptPasswordEncoder();
		return encoder;
	}

}
